package com.shycloud.mido.member.handler;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shycloud.mido.common.core.constant.CommonConstants;
import com.shycloud.mido.common.core.constant.SecurityConstants;
import com.shycloud.mido.common.core.constant.enums.LoginTypeEnum;
import com.shycloud.mido.member.api.entity.*;
import com.shycloud.mido.member.api.vo.MemberDetailForLoginVO;
import com.shycloud.mido.member.mapper.MemSocialDetailsMapper;
import com.shycloud.mido.member.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 微信登录
 *
 * @author nianhua.jiang
 */
@Slf4j
@Component("WX")
@AllArgsConstructor
public class WeChatLoginHandler extends AbstractLoginHandler {

	private final MemSocialDetailsMapper memSocialDetailsMapper;
	/** 会员模块 service */
	private final MemberServiceV2 memberService;
	/** 教师模块 service */
	private final OrgTeacherDetailedService teacherDetailedService;
	/** 学生模块 service */
	private final OrgStudentDetailedService studentDetailedService;
	/** 机构模块 service */
	private final OrgOrganizationService orgOrganizationService;
	/** redis 模块 */
	private final RedisTemplate redisTemplate;

	/**
	 * 微信登录传入code
	 * <p>
	 * 通过code 调用qq 获取唯一标识
	 *
	 * @param code
	 * @return
	 */
	@Override
	public String identify(String code) {

		MemSocialDetails condition = new MemSocialDetails();
		condition.setType(LoginTypeEnum.WECHAT.getType());
		MemSocialDetails socialDetails = memSocialDetailsMapper.selectOne(new QueryWrapper<>(condition));

		String url = String.format(SecurityConstants.WX_AUTHORIZATION_CODE_URL, socialDetails.getAppId(), socialDetails.getAppSecret(), code);
		String result = HttpUtil.get(url);

		System.out.println("=========================微信响应报文:{" + result + "}");

		Object obj = JSONUtil.parseObj(result).get("openid");

		if (obj == null) {
			return null;
		}

		String token = JSONUtil.parseObj(result).get("access_token").toString();

		redisTemplate.opsForValue().set("wxOpenId_" + obj.toString(), token);

		//保存token信息
		return obj.toString();
	}

	/**
	 * openId 获取用户信息
	 *
	 * @param openId
	 * @return
	 */
	@Override
	public MemberDetailForLoginVO info(String openId) {

		Member member = memberService.getOne(new QueryWrapper<Member>().eq("wx_openid", openId));

		MemberDetailForLoginVO memberDetailForLoginVO = new MemberDetailForLoginVO();

		//TODO 微信没有绑定用户的场合
		if (member == null) {
			memberDetailForLoginVO.setWxOpenid(openId);
			memberDetailForLoginVO.setStatus("3");
			return memberDetailForLoginVO;
		}

		//更新用户 头像/昵称
		String token = redisTemplate.opsForValue().get("wxOpenId_" + openId).toString();

		//根据 token 获取头像，昵称等个人信息
		String url = String.format(SecurityConstants.WX_USER_INFO_URL, token, openId);

		String result = HttpUtil.get(url);
		System.out.println("=========================微信登录响应用户信息:{" + result + "}");

		if (!result.isEmpty()) {
			//微信昵称
			String nickName = JSONUtil.parseObj(result).get("nickname").toString();
			//微信头像
			String header = JSONUtil.parseObj(result).get("headimgurl").toString();
			//性别
			//String sex = JSONUtil.parseObj(result).get("sex").toString();
			member.setShowname(nickName);
			member.setAvatar(header);
			memberService.updateById(member);
		}

		BeanUtils.copyProperties(member, memberDetailForLoginVO);

		//身份为教师
		if ("1".equals(memberDetailForLoginVO.getIsTeacher())) {
			//查询教师表，获取默认机构ID
			List<OrgTeacherDetailed> teacherDetaileds = teacherDetailedService.list(new QueryWrapper<OrgTeacherDetailed>()
					.eq(OrgTeacherDetailed.COL_MEMBER_ID, memberDetailForLoginVO.getId())
					.and(x -> x.eq(OrgTeacherDetailed.COL_DEL_FLAG, "0"))
					.orderByAsc(OrgTeacherDetailed.COL_CREATE_TIME));

			if (teacherDetaileds.size() == 0) {
				log.info("未查询到所在机构，用户名为:{}", memberDetailForLoginVO.getUsername());
				return null;
			} else {
				//获取机构信息
				OrgOrganization org = orgOrganizationService.getById(teacherDetaileds.get(0).getOrgId());
				//机构ID
				memberDetailForLoginVO.setOrgId(org.getId());
				//机构名
				memberDetailForLoginVO.setOrgName(org.getName());
			}

		}

		//身份为学生
		else {
			//查询学生表，获取默认机构ID
			List<OrgStudentDetailed> studentDetaileds = studentDetailedService.list(new QueryWrapper<OrgStudentDetailed>()
					.eq(OrgStudentDetailed.COL_MEMBER_ID, memberDetailForLoginVO.getId())
					.and(x -> x.eq(OrgStudentDetailed.COL_DEL_FLAG, "0"))
					.orderByAsc(OrgStudentDetailed.COL_CREATE_TIME));

			if (studentDetaileds.size() > 0) {

				if (studentDetaileds.get(0).getOrgId() != 0) {
					//获取机构信息
					OrgOrganization org = orgOrganizationService.getById(studentDetaileds.get(0).getOrgId());
					//机构ID
					memberDetailForLoginVO.setOrgId(org.getId());
					//机构名
					memberDetailForLoginVO.setOrgName(org.getName());
				} else {
					//机构ID
					memberDetailForLoginVO.setOrgId(0);
					//机构名
					memberDetailForLoginVO.setOrgName("暂无机构");
				}

			} else {

				//false 代表 redis 有这个键就不能继续操作了
				Boolean saveStudentRedis = redisTemplate.opsForValue().setIfAbsent("saveStudent_" + member.getId(), "1", 5, TimeUnit.SECONDS);
				if (saveStudentRedis) {
					//新建学生身份，orgId为0，暂无机构
					//创建学生用户
					OrgStudentDetailed student = new OrgStudentDetailed();
					//memberId
					student.setMemberId(memberDetailForLoginVO.getId());
					//机构ID
					student.setOrgId(0);
					//创建时间
					student.setCreateTime(new Date());
					//逻辑删除
					student.setDelFlag(CommonConstants.STATUS_NORMAL);
					//昵称
					student.setName(memberDetailForLoginVO.getShowname());

					studentDetailedService.save(student);
				}
				//机构ID
				memberDetailForLoginVO.setOrgId(0);
				//机构名
				memberDetailForLoginVO.setOrgName("暂无机构");
			}
		}
		return memberDetailForLoginVO;
	}
}
